package com.jeesite.modules.web;

import com.jeesite.modules.auth.entity.Authme;
import com.jeesite.modules.common.Result;
import com.jeesite.modules.auth.entity.AuthUser;
import com.jeesite.modules.exception.BusinessException;
import com.jeesite.modules.service.UserService;
import com.jeesite.modules.utils.JwtUtils;
import com.jeesite.modules.utils.RedisUtils;
import com.jeesite.common.network.IpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录控制器
 * 处理用户登录、注册、Token验证等功能
 */
@RestController
@RequestMapping("/auth")
public class AuthController {
    
    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private RedisUtils redisUtils;
    
    @Autowired
    @Qualifier("authUserService")
    private UserService userService;
    
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthmeController authmeController;
    /**
     * 用户登录
     */
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@RequestBody LoginRequest request, HttpServletRequest httpRequest) {
        try {
            // 参数校验
            if (!StringUtils.hasText(request.getUsername()) || !StringUtils.hasText(request.getPassword())) {
                return Result.fail("用户名和密码不能为空");
            }
            
            // 获取客户端IP
            //String loginIp = IpUtils.getRemoteAddr(httpRequest);
            
            // 查找用户
            AuthUser user = userService.findByUsername(request.getUsername());
            if (user == null) {
                return Result.fail("用户不存在");
            }
            
            // 检查用户状态
            if (!"ACTIVE".equals(user.getStatus())) {
                return Result.fail("用户已被禁用");
            }
            
            // 验证密码
            if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
                return Result.fail("用户名或密码错误");
            }
            
            // 生成Token
            String token = jwtUtils.generateToken(user.getUsername(), Long.parseLong(user.getId()));
            String refreshToken = jwtUtils.generateRefreshToken(user.getUsername(), Long.parseLong(user.getId()));
            
            // 存储到Redis
            redisUtils.setToken(user.getUsername(), token, 86400); // 24小时
            redisUtils.setRefreshToken(user.getUsername(), refreshToken, 604800); // 7天
            redisUtils.setUser(user.getUsername(), user, 86400);
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("refreshToken", refreshToken);
            result.put("userInfo", Map.of(
                "id", user.getId(),
                "username", user.getUsername(),
                "nickname", user.getNickname(),
                "email", "",
                "avatar", user.getAvatar() != null ? user.getAvatar() : "https://trae-api-us.mchost.guru/api/ide/v1/text_to_image?prompt=default%20user%20avatar%20icon%20modern%20style&image_size=square"
            ));
            
            logger.info("用户登录成功: {}", user.getUsername());
            return Result.success("登录成功", result);
            
        } catch (Exception e) {
            logger.error("登录异常", e);
            return Result.fail("登录失败: " + e.getMessage());
        }
    }
    
    /**
     * 用户注册
     */
    @PostMapping("/register")
    public Result<String> register(@RequestBody RegisterRequest request) {
        try {
            // 参数校验
            if (!StringUtils.hasText(request.getUsername()) || 
                !StringUtils.hasText(request.getPassword()) ||
                !StringUtils.hasText(request.getNickname())) {
                return Result.fail("用户名、密码和昵称不能为空");
            }
            
            // 密码长度校验
            if (request.getPassword().length() < 6) {
                return Result.fail("密码长度不能少于6位");
            }
            
            // 检查用户是否已存在
            AuthUser existingUser = userService.findByUsername(request.getUsername());
            if (existingUser != null) {
                return Result.fail("用户已存在");
            }
            //检查用户是否在游戏中进行注册
            Authme authme = authmeController.getByRealname(request.getUsername());
            if (authme == null) {
                return Result.fail("用户并未在游戏里面注册，请先在服务器中进行游戏的注册");
            }
            
            // 创建新用户
            AuthUser newUser = new AuthUser();
            newUser.setUsername(request.getUsername());
            newUser.setPassword(passwordEncoder.encode(request.getPassword()));
            newUser.setNickname(request.getNickname());
            
            // 保存用户
            userService.save(newUser);
            
            logger.info("用户注册成功: {}", request.getUsername());
            return Result.success("注册成功");
            
        } catch (RuntimeException e) {
            logger.error("注册异常: {}", e.getMessage());
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            logger.error("注册异常", e);
            return Result.fail("注册失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取用户信息
     */
    @GetMapping("/userinfo")
    public Result<Map<String, Object>> getUserInfo(HttpServletRequest request) {
        try {
            String token = getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.unauthorized("Token不能为空");
            }
            
            // 验证Token
            if (!jwtUtils.validateToken(token)) {
                return Result.unauthorized("Token无效或已过期");
            }
            
            // 获取用户信息
            String username = jwtUtils.getUsernameFromToken(token);
            AuthUser user = userService.findByUsername(username);
            if (user == null) {
                return Result.fail("用户不存在");
            }

            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("id", user.getId());
            userInfo.put("username", user.getUsername());
            userInfo.put("nickname", user.getNickname());
            userInfo.put("role", user.getRole());
            userInfo.put("avatar", user.getAvatar() != null ? user.getAvatar() : "https://trae-api-us.mchost.guru/api/ide/v1/text_to_image?prompt=default%20user%20avatar%20icon%20modern%20style&image_size=square");
            
            return Result.success(userInfo);
            
        } catch (Exception e) {
            logger.error("获取用户信息异常", e);
            return Result.fail("获取用户信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 刷新Token
     */
    @PostMapping("/refresh")
    public Result<Map<String, Object>> refreshToken(@RequestBody RefreshTokenRequest request) {
        try {
            String refreshToken = request.getRefreshToken();
            if (!StringUtils.hasText(refreshToken)) {
                return Result.fail("刷新Token不能为空");
            }
            
            // 验证刷新Token
            if (!jwtUtils.validateToken(refreshToken)) {
                return Result.unauthorized("刷新Token无效或已过期");
            }
            
            // 获取用户信息
            String username = jwtUtils.getUsernameFromToken(refreshToken);
            Long userId = jwtUtils.getUserIdFromToken(refreshToken);
            
            // 检查Redis中的刷新Token
            String cachedRefreshToken = redisUtils.getRefreshToken(username);
            if (!refreshToken.equals(cachedRefreshToken)) {
                return Result.unauthorized("刷新Token不匹配");
            }
            
            // 生成新的Token
            String newToken = jwtUtils.generateToken(username, userId);
            String newRefreshToken = jwtUtils.generateRefreshToken(username, userId);
            
            // 更新Redis
            redisUtils.setToken(username, newToken, 86400);
            redisUtils.setRefreshToken(username, newRefreshToken, 604800);
            
            Map<String, Object> result = new HashMap<>();
            result.put("token", newToken);
            result.put("refreshToken", newRefreshToken);
            
            logger.info("Token刷新成功: {}", username);
            return Result.success("Token刷新成功", result);
            
        } catch (Exception e) {
            logger.error("Token刷新异常", e);
            return Result.fail("Token刷新失败: " + e.getMessage());
        }
    }
    
    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public Result<String> logout(HttpServletRequest request) {
        try {
            String token = getTokenFromRequest(request);
            if (StringUtils.hasText(token)) {
                String username = jwtUtils.getUsernameFromToken(token);
                if (StringUtils.hasText(username)) {
                    // 清除Redis中的用户缓存
                    redisUtils.clearUserCache(username);
                    logger.info("用户登出成功: {}", username);
                }
            }
            return Result.success("登出成功");
        } catch (Exception e) {
            logger.error("登出异常", e);
            return Result.fail("登出失败: " + e.getMessage());
        }
    }
    
    /**
     * 服务器状态查询
     */
    @GetMapping("/server-status")
    public Result<Map<String, Object>> getServerStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("status", "online");
        status.put("players", "15/100");
        status.put("version", "1.20.1");
        status.put("motd", "欢迎来到我的世界服务器！");
        status.put("uptime", "2天3小时45分钟");
        return Result.success(status);
    }
    
    /**
     * 修改密码
     */
    @PostMapping("/change-password")
    public Result<String> changePassword(@RequestBody ChangePasswordRequest request, HttpServletRequest httpRequest) {
        try {
            String token = getTokenFromRequest(httpRequest);
            if (!StringUtils.hasText(token)) {
                return Result.unauthorized("Token不能为空");
            }
            
            // 验证Token
            if (!jwtUtils.validateToken(token)) {
                return Result.unauthorized("Token无效或已过期");
            }
            
            // 参数校验
            if (!StringUtils.hasText(request.getOldPassword()) || !StringUtils.hasText(request.getNewPassword())) {
                return Result.fail("旧密码和新密码不能为空");
            }
            
            if (request.getNewPassword().length() < 6) {
                return Result.fail("新密码长度不能少于6位");
            }
            
            // 获取当前用户
            String username = jwtUtils.getUsernameFromToken(token);
            AuthUser user = userService.findByUsername(username);
            if (user == null) {
                return Result.fail("用户不存在");
            }
            
            // 验证旧密码
            if (!passwordEncoder.matches(request.getOldPassword(), user.getPassword())) {
                return Result.fail("旧密码错误");
            }
            
            // 更新密码
            user.setPassword(passwordEncoder.encode(request.getNewPassword()));
            userService.update(user);
            
            // 更新Redis中的用户信息
            redisUtils.setUser(username, user, 86400);
            
            logger.info("用户修改密码成功: {}", username);
            return Result.success("密码修改成功");
            
        } catch (Exception e) {
            logger.error("修改密码异常", e);
            return Result.fail("修改密码失败: " + e.getMessage());
        }
    }
    
    /**
     * 修改昵称
     */
    @PostMapping("/update-nickname")
    public Result<String> updateNickname(@RequestBody UpdateNicknameRequest request, HttpServletRequest httpRequest) {
        try {
            String token = getTokenFromRequest(httpRequest);
            if (!StringUtils.hasText(token)) {
                return Result.unauthorized("Token不能为空");
            }
            
            // 验证Token
            if (!jwtUtils.validateToken(token)) {
                return Result.unauthorized("Token无效或已过期");
            }
            
            // 参数校验
            if (!StringUtils.hasText(request.getNickname())) {
                return Result.fail("昵称不能为空");
            }
            
            if (request.getNickname().length() > 20) {
                return Result.fail("昵称长度不能超过20个字符");
            }
            
            // 获取当前用户
            String username = jwtUtils.getUsernameFromToken(token);
            AuthUser user = userService.findByUsername(username);
            if (user == null) {
                return Result.fail("用户不存在");
            }
            
            // 更新昵称
            user.setNickname(request.getNickname());
            userService.update(user);
            
            // 更新Redis中的用户信息
            redisUtils.setUser(username, user, 86400);
            
            logger.info("用户修改昵称成功: {} -> {}", username, request.getNickname());
            return Result.success("昵称修改成功");
            
        } catch (Exception e) {
            logger.error("修改昵称异常", e);
            return Result.fail("修改昵称失败: " + e.getMessage());
        }
    }
    
    /**
     * 修改头像
     */
    @PostMapping("/update-avatar")
    public Result<String> updateAvatar(@RequestBody UpdateAvatarRequest request, HttpServletRequest httpRequest) {
        try {
            String token = getTokenFromRequest(httpRequest);
            if (!StringUtils.hasText(token)) {
                return Result.unauthorized("Token不能为空");
            }
            
            // 验证Token
            if (!jwtUtils.validateToken(token)) {
                return Result.unauthorized("Token无效或已过期");
            }
            
            // 参数校验
            if (!StringUtils.hasText(request.getAvatarUrl())) {
                return Result.fail("头像URL不能为空");
            }
            
            // 获取当前用户
            String username = jwtUtils.getUsernameFromToken(token);
            AuthUser user = userService.findByUsername(username);
            if (user == null) {
                return Result.fail("用户不存在");
            }
            
            // 更新头像
            user.setAvatar(request.getAvatarUrl());
            userService.update(user);
            
            // 更新Redis中的用户信息
            redisUtils.setUser(username, user, 86400);
            
            logger.info("用户修改头像成功: {}", username);
            return Result.success("头像修改成功");
            
        } catch (Exception e) {
            logger.error("修改头像异常", e);
            return Result.fail("修改头像失败: " + e.getMessage());
        }
    }
    
    /**
     * 从请求中获取Token
     */
    private String getTokenFromRequest(HttpServletRequest request) {
        return request.getHeader("access-key");
    }

    // 内部类定义
    public static class LoginRequest {
        private String username;
        private String password;
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
    
    public static class RegisterRequest {
        private String username;
        private String password;
        private String nickname;
        private String email;
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getNickname() { return nickname; }
        public void setNickname(String nickname) { this.nickname = nickname; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
    }
    
    public static class RefreshTokenRequest {
        private String refreshToken;
        
        public String getRefreshToken() { return refreshToken; }
        public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; }
    }
    
    public static class ChangePasswordRequest {
        private String oldPassword;
        private String newPassword;
        
        public String getOldPassword() { return oldPassword; }
        public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; }
        public String getNewPassword() { return newPassword; }
        public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
    }
    
    public static class UpdateNicknameRequest {
        private String nickname;
        
        public String getNickname() { return nickname; }
        public void setNickname(String nickname) { this.nickname = nickname; }
    }
    
    public static class UpdateAvatarRequest {
        private String avatarUrl;
        
        public String getAvatarUrl() { return avatarUrl; }
        public void setAvatarUrl(String avatarUrl) { this.avatarUrl = avatarUrl; }
    }

}